package org.naxx.security.test.unit.dev.parser;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;

import org.apache.log4j.Logger;
import org.naxx.security.Main;
import org.naxx.security.parser.validation.SchemaValidator;
import org.naxx.security.util.Assert;
import org.naxx.security.util.FileSystemUtil;

import junit.framework.TestCase;

public abstract class AbstractSingleFileParsingTestCase extends TestCase {

	private static Main m = null; // FIXME hack, load app context
	private static final Logger logger = Logger.getLogger(AbstractSingleFileParsingTestCase.class);

	protected InputStream in;
	protected XMLEventReader reader;
	
	protected abstract String getFileName();
	
	protected boolean shouldValidateAgainstXacmlSchema() {
		return true;
	}

	protected void setUp() throws Exception {
		if(this.shouldValidateAgainstXacmlSchema()) {
			this.validateAgainstSchema();
		}
		this.in = new FileInputStream(new File(this.getFileName()));
		this.reader = XMLInputFactory.newInstance().createXMLEventReader(this.in);
	}
	
	protected void tearDown() throws Exception {
		FileSystemUtil.release(this.reader);
		FileSystemUtil.close(this.in);
	}
	
	// PERFORMANCE add support to read file once but create from it
	// two in memory streams for performance reasons
	private void validateAgainstSchema() throws Exception {
		InputStream in = null;
		try {
			File file = new File(this.getFileName());
			Assert.assertFileExistsAndReadable(file);
			in = new FileInputStream(file);
			Main.getRepository().getService(SchemaValidator.class).validate(in);
		} catch (Exception e) {
			String errorMessage = "File '" + this.getFileName() + "' is not valid according to" +
					" XACML schema";
			logger.error(errorMessage, e);
			throw new IllegalArgumentException(errorMessage);
		} finally {
			FileSystemUtil.close(in);
		}
	}
}
